\section{Fonctionnement global}

\subsection{Structures et entités}
Afin de pouvoir manipuler les \textit{threads}, une structure \verb+thread+ a été mise en place et contient son contexte, un pointeur vers un \textit{thread} qui \og{}attend\fg{} ce \textit{thread}, une valeur de retour ainsi qu'une priorité (utilisée pour la préemption). Ces structures sont stockées dans 3 listes différentes en fonction de l'état du \textit{thread} associé. Un pointeur vers le \textit{thread} en cours d'exécution est également utilisé, ainsi qu'un pointeur vers le \textit{thread} correspondant au \textit{main}.

\subsection{Listes}
Une première liste contient les \textit{threads} actifs, une autre les \textit{threads} \og{}endormis\fg{}, et une troisième contient les \textit{threads} terminés. Nous utilisions précédemment des listes de type \textsf{GList}, mais leur implémentation est telle que \textsf{Valgrind} détecte des erreurs qui n'en sont pas vraiment. Afin de pouvoir vérifier correctement la gestion de la mémoire du programme, nous avons donc finalement utilisé des listes que nous avons implémentées nous-mêmes.

\subsection{Initialisation}
Au lancement d'un programme ayant inclus la bibliothèque, une fonction de type \textsf{\_\_attribute\_\_((constructor))} est appelée et effectue l'initialisation des 3 listes. Le \verb+main+ est également considéré comme un \textit{thread} en assignant le pointeur global associé. Une pile alternative est également créée pour assurer la gestion des débordements de pile par les \textit{threads}.

\subsection{Création d'un \textit{thread}}
Lors de la création d'un \textit{thread} à l'aide de la fonction \verb+thread_create()+, un nouveau contexte est créé avec la fonction passée en paramètre. La mémoire du \textit{thread} est allouée et le \textit{thread} est ajouté à la liste des \textit{threads} actifs.

\subsection{Passage de main entre \textit{threads}}
Cette possibilité est offerte grâce aux fonctions \verb+thread_next()+ et \verb+thread_yield()+. La dernière consiste à ajouter le \textit{thread} à la fin de la liste des \textit{threads} actifs et à appeler \verb+thread_next()+. Cette fonction récupère le premier \textit{thread} de la liste des \textit{threads} actifs et le place à la place du \textit{thread} en exécution. Remarquons que cette fonction ne fait aucune opération sur le précédent \textit{thread} en exécution : c'est aux fonctions appelantes de le sauvegarder / placer dans une liste. Enfin, un changement de contexte est effectué. Lorsque la liste des \textit{threads} actifs est vide, le contexte du main est restauré afin de libérer la mémoire des \textit{threads} et quitter proprement le programme.

\subsection{Attente d'un \textit{thread}}
La fonction \verb+thread_join()+ permet d'attendre un \textit{thread}. Deux cas sont possibles. Dans le premier cas, le \textit{thread} qu'on doit attendre est déjà terminé et il se trouve dans la liste des \textit{threads} terminés. On récupère alors la valeur de retour si nécessaire et on sort de la fonction. Dans le deuxième cas, le \textit{thread} n'est pas terminé et on se met dans la liste des processus endormis et on met à jour la structure du processus attendu en lui spécifiant qu'on l'attend.

\subsection{Fin d'un \textit{thread}}
Lorsqu'un \textit{thread} appelle la fonction \verb+thread_exit()+, on stocke la valeur passée en paramètre qui correspond à la valeur de retour dans la structure du \textit{thread}. On ajoute le \textit{thread} à la liste des processus terminés. Si un processus nous attend, on le réveille, puis on passe la main à un autre processus. Pour que ce mécanisme fonctionne même si l'utilisateur n'appelle pas \verb+thread_exit()+ à la fin des ces fonctions, lors de la création d'un \textit{thread}, la fonction appelée n'est pas directement la fonction passée en paramètre mais \verb+thread_exec()+ qui se charge d'appeler la fonction en récupérant la valeur de retour et d'appeler \verb+thread_exit()+ avec cette valeur.

\subsection{Connaissance du \textit{thread} courant}
La fonction \verb+thread_self()+ renvoie simplement le pointeur du \textit{thread} en exécution.

\subsection{Préemption des \textit{threads}}
La préemption des \textit{threads} a été réalisée à l'aide d'un \textit{timer}. Chaque fois que l'on rend la main à un \textit{thread}, on initialise un \textit{timer} qui, quand il arrive à 0, envoie un signal \textsf{SIGVALARM}. En mettant en place un gestionnaire de signaux pour ce signal en particulier, on peut récupérer la main et on peut ainsi appeler la fonction \verb+thread_yield()+ et donc passer la main à un autre \textit{thread}. À chaque fois qu'une fonction touchant à la gestion des \textit{threads} est appelée, il faut désactiver le \textit{timer} pour éviter de se faire préempter à un moment où nos structures de données sont dans des états incohérents.

\subsection{Priorité}
Dans chaque structure décrivant un \textit{thread}, il y a un entier définissant la priorité du \textit{thread}. Pour définir cet entier, une méthode \verb+thread_priority()+ a été ajoutée. Elle prend en paramètre un \verb+thread_t+ et un entier et met à jour la priorité du \textit{thread} en fonction de l'entier. Les priorités varient entre -20 et 20 avec comme priorité par défaut 0. Pour l'instant la priorité influe sur la durée du \textit{timer} de la préemption. Et donc plus la priorité est petite, plus la \textit{time slice} du processus en cours sera long et vice versa.

\subsection{Gestion de la mémoire}
Deux allocations de mémoire sont à gérer. Une est effectuée par l'ajout dans une des listes, l'autre est effectuée pour allouer la mémoire d'un \textit{thread}. Nous utilisons la fonction \verb+list_remove()+ pour libérer la mémoire de la liste et la fonction \verb+thread_free()+ pour libérer la mémoire du \textit{thread}. La mémoire est libérée dans deux situations : dans la fonction \verb+thread_join()+ et à la fin du programme. Dans le premier cas, si le \textit{thread} que l'on doit attendre est déjà terminé (il se trouve dans la liste des \textit{threads} terminés), on peut alors l'enlever de cette liste et libérer la mémoire du \textit{thread}. En effet, le manuel de \verb+pthread_join()+ nous indique qu'au plus un seul \textit{thread} peut attendre la mort d'un \textit{thread} donné. Notre fonction renvoie une erreur si l'utilisateur effectue deux \verb+thread_join()+ sur le même \textit{thread}. Mais elle ne gère pas encore le cas où le \textit{thread} que l'on doit attendre a déjà été attendu. Dans le second cas (terminaison du programme) grâce à \verb+__attribute__((destructor))+, nous pouvons libérer correctement la mémoire. Nous utilisons une fonction dédiée \verb+queue_free()+ pour libérer la mémoire des \textit{threads} dans les listes et des éléments de la liste et nous libérons également le \textit{thread} en exécution.
